package com.roc.demo.fault.retry;

import com.github.rholder.retry.*;
import com.roc.demo.model.RpcResponse;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 固定时间间隔 - 重试策略
 */
@Slf4j
public class FixedIntervalRetryStrategy implements RetryStrategy {

    /**
     * 重试
     *
     * @param callable
     * @return
     * @throws ExecutionException
     * @throws RetryException
     */
    public RpcResponse doRetry(Callable<RpcResponse> callable) throws ExecutionException, RetryException {
        Retryer<RpcResponse> retry = RetryerBuilder.<RpcResponse>newBuilder()
                .retryIfExceptionOfType(Exception.class)  //重试策略：当捕获到 Exception 类型的异常时，执行重试
                .withWaitStrategy(WaitStrategies.fixedWait(3L, TimeUnit.SECONDS)) //等待策略：在每次重试之间，固定等待 3 秒钟。
                .withStopStrategy(StopStrategies.stopAfterAttempt(3)) //停止策略：最多重试 3 次。
                .withRetryListener(new RetryListener() {  //添加重试监听器：在每次重试时执行的逻辑。重试的次数会被记录到日志中。
                    @Override
                    public <V> void onRetry(Attempt<V> attempt) {
                        log.info("重试次数 {}", attempt.getAttemptNumber());
                    }
                })
                .build();
        return retry.call(callable);
    }

}
